package com.spring.controller.dao;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Repository;

import com.spring.controller.dto.RedisDTO;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.exceptions.JedisConnectionException;


@Repository("jedisDao")
@SuppressWarnings({ "rawtypes", "unchecked" })
public class JedisDao {

	@Autowired
	private JedisPoolUtil jedisPoolUtil;

	@Value("${jedis.continuetime}")
	private Integer continuetime;
	
	/**
	 * 保存字符串（带自动销毁）
	 * @param key 关键字
	 * @param jsonString 保存的字符串
	 * @param mtimeout 自动销毁时间(s)【-1：不设置，0：默认时间】
	 * @return
	 */
	public boolean setString(String key,String jsonString,int mtimeout){
		Jedis jedis = jedisPoolUtil.getResource();
		try {
			jedis.set(key, jsonString);
			if (mtimeout != -1) {
				if (mtimeout == 0) {
					jedis.expire(key, continuetime);
				}else {
					jedis.expire(key, mtimeout);
				}
			}
		} catch (JedisConnectionException e) {
			// 释放redis对象
			jedisPoolUtil.returnBrokenResource(jedis);
			e.printStackTrace();
			return false;
		} finally {
			// 返还到连接池
			jedisPoolUtil.returnResource(jedis);
		}
		return true;
	}

	/**
	 * 仅获取json数据
	 */
	public  String getString(String key) {
		String value = null;
		Jedis jedis = jedisPoolUtil.getResource();
		try {
			value = jedis.get(key);
		} catch (Exception e) {
			// 释放redis对象
			e.printStackTrace();
		} finally {
			// 返还到连接池
			jedisPoolUtil.returnResource(jedis);
		}
		return value;
	}
	
	/**
	 * 保存对象（带自动销毁）
	 * @param key 关键字
	 * @param dto 对象
	 * @param mtimeout 自动销毁时间(s)【-1：不设置，0：默认时间】
	 * @return
	 */
	public boolean setObject(String key, Object dto,int mtimeout){
		Jedis jedis = jedisPoolUtil.getResource();
		try {
			JSONArray testjson = JSONArray.fromObject(dto);  
			jedis.set(key, testjson.toString());
			if (mtimeout != -1) {
				if (mtimeout == 0) {
					jedis.expire(key, continuetime);
				}else {
					jedis.expire(key, mtimeout);
				}
			}
		} catch (JedisConnectionException e) {
			// 释放redis对象
			jedisPoolUtil.returnBrokenResource(jedis);
			e.printStackTrace();
			return false;
		} finally {
			// 返还到连接池
			jedisPoolUtil.returnResource(jedis);
		}
		return true;
	}
	
	/**
	 * 更新对象的销毁时间
	 * @param key 关键字
	 * @param mtimeout 自动销毁时间(s)【-1：不设置，0：默认时间】
	 * @return
	 */
	public boolean updatetime(String key,int mtimeout){
		Jedis jedis = jedisPoolUtil.getResource();
		try {
			if (mtimeout != 0) {
				jedis.expire(key, mtimeout);
			}else{
				jedis.expire(key, continuetime);
			}
		} catch (JedisConnectionException e) {
			// 释放redis对象
			jedisPoolUtil.returnBrokenResource(jedis);
			e.printStackTrace();
			return false;
		} finally {
			// 返还到连接池
			jedisPoolUtil.returnResource(jedis);
		}
		return true;
	}

	/**
	 * 根据key删除数据
	 * @param key 关键字
	 * @return
	 */
	public boolean delString(String key){
		Jedis jedis = jedisPoolUtil.getResource();
		try {
			jedis.del(key);
		} catch (JedisConnectionException e) {
			// 释放redis对象
			jedisPoolUtil.returnBrokenResource(jedis);
			e.printStackTrace();
			return false;
		} finally {
			// 返还到连接池
			jedisPoolUtil.returnResource(jedis);
		}
		return true;
	}
	
	/**
	 * 取RedisDTO
	 * @param key 关键字
	 * @return
	 */
	public RedisDTO getRedisDto(String key) {
		try {
			String loginjson = getString(key);
			if (loginjson == null) {
				return null;
			}
			RedisDTO userlogin = new RedisDTO();
			JSONObject json = JSONObject.fromObject(loginjson.substring(1, loginjson.length()-1));
			Map<String, Class> classMap = new HashMap<String, Class>(); 
			//存在List时，加入以下代码
			//	例子：classMap.put("roles", RoleDTO.class);
			userlogin = (RedisDTO) JSONObject.toBean(json, RedisDTO.class,classMap);
			return userlogin;
		} catch (Exception e) {
			return null;
		}
	}
	
	/**
	 * 取<T>对象 T 
	 * @param key 关键字
	 * @param t 泛型
	 * @return
	 */
	public <T> T getObject(String key,T t){
		try {
			String loginjson = getString(key);
			if (loginjson == null) {
				return null;
			}
			JSONObject json = JSONObject.fromObject(loginjson.substring(1, loginjson.length()-1));
			Map<String, Class> classMap = new HashMap<String, Class>(); 
			//存在List时，加入以下代码
			//	例子：classMap.put("roles", RoleDTO.class);
			t= (T) JSONObject.toBean(json, t.getClass(),classMap);
			return t;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	
	/**
	 * 从redis中取key对应的对象，同时更新对象的超时销毁时间
	 * @param key
	 * @param t
	 * @param time	超时时间
	 * @return
	 */
	public  <T> T getObject(String key, T t, int time) {
		try {
			String loginjson = getString(key);
			if (loginjson == null) {
				return null;
			}
			// 如果设置有超时时间，则更新
			if (time > 0) {
				updatetime(key, time);
			}
			JSONObject json = JSONObject.fromObject(loginjson.substring(1, loginjson.length()-1));
			Map<String, Class> classMap = new HashMap<String, Class>(); 
			//存在List时，加入以下代码
			//	例子：classMap.put("roles", RoleDTO.class);
			t= (T) JSONObject.toBean(json, t.getClass(),classMap);
			return t;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	
	/******************************************redis队列可能调用新方法********************************************/
	//返还到连接池
	public void close(Jedis jedis) {
        try {
        	jedisPoolUtil.returnResource(jedis);
        } catch (Exception e) {
            if (jedis.isConnected()) {
                jedis.quit();
                jedis.disconnect();
            }
        }
    }
	
	/**
     * 获取数据
     * 
     * @param key
     * @return
     */
    public byte[] get(byte[] key) {
        byte[] value = null;
        Jedis jedis = null;
        try {
            jedis = jedisPoolUtil.getResource();
            value = jedis.get(key);
        } catch (Exception e) {
            //释放redis对象
        	jedisPoolUtil.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            //返还到连接池
            close(jedis);
        }
 
        return value;
    }
	
    public void set(byte[] key, byte[] value) {
        Jedis jedis = null;
        try {
            jedis = jedisPoolUtil.getResource();
            jedis.set(key, value);
        } catch (Exception e) {
            //释放redis对象
        	jedisPoolUtil.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            //返还到连接池
            close(jedis);
        }
    }
    
    public void set(byte[] key, byte[] value, int time) {
        Jedis jedis = null;
        try {
            jedis = jedisPoolUtil.getResource();
            jedis.set(key, value);
            jedis.expire(key, time);
        } catch (Exception e) {
            //释放redis对象
        	jedisPoolUtil.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            //返还到连接池
            close(jedis);
        }
    }
    
    public void hset(byte[] key, byte[] field, byte[] value) {
        Jedis jedis = null;
        try {
            jedis = jedisPoolUtil.getResource();
            jedis.hset(key, field, value);
        } catch (Exception e) {
            //释放redis对象
        	jedisPoolUtil.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            //返还到连接池
            close(jedis);
        }
    }
    
    public void hset(String key, String field, String value) {
        Jedis jedis = null;
        try {
            jedis = jedisPoolUtil.getResource();
            jedis.hset(key, field, value);
        } catch (Exception e) {
            //释放redis对象
        	jedisPoolUtil.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            //返还到连接池
            close(jedis);
        }
    }
    
    
    /**
     * 获取数据
     * @param key
     * @return
     */
    public String hget(String key, String field) {
        String value = null;
        Jedis jedis = null;
        try {
            jedis = jedisPoolUtil.getResource();
            value = jedis.hget(key, field);
        } catch (Exception e) {
            //释放redis对象
        	jedisPoolUtil.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            //返还到连接池
            close(jedis);
        }
        return value;
    }
    
    /**
     * 获取数据
     * @param key
     * @return
     */
    public byte[] hget(byte[] key, byte[] field) {
        byte[] value = null;
        Jedis jedis = null;
        try {
            jedis = jedisPoolUtil.getResource();
            value = jedis.hget(key, field);
        } catch (Exception e) {
            //释放redis对象
        	jedisPoolUtil.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            //返还到连接池
            close(jedis);
        }
        return value;
    }
    
    public void hdel(byte[] key, byte[] field) {
        Jedis jedis = null;
        try {
            jedis = jedisPoolUtil.getResource();
            jedis.hdel(key, field);
        } catch (Exception e) {
            //释放redis对象
        	jedisPoolUtil.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            //返还到连接池
            close(jedis);
        }
    }
    
    /**
     * 存储REDIS队列 顺序存储
     * @param byte[] key reids键名
     * @param byte[] value 键值
     */
    public void lpush(byte[] key, byte[] value) {
        Jedis jedis = null;
        try {
            jedis = jedisPoolUtil.getResource();
            jedis.lpush(key, value);
        } catch (Exception e) {
            //释放redis对象
        	jedisPoolUtil.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            //返还到连接池
            close(jedis);
        }
    }
    
    /**
     * 存储REDIS队列 反向存储
     * @param byte[] key reids键名
     * @param byte[] value 键值
     */
    public void rpush(byte[] key, byte[] value) {
        Jedis jedis = null;
        try {
            jedis = jedisPoolUtil.getResource();
            jedis.rpush(key, value);
        } catch (Exception e) {
            //释放redis对象
        	jedisPoolUtil.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            //返还到连接池
            close(jedis);
        }
    }
    
    /**
     * 将列表 source 中的最后一个元素(尾元素)弹出，并返回给客户端
     * @param byte[] key reids键名
     * @param byte[] value 键值
     */
    public void rpoplpush(byte[] key, byte[] destination) {
        Jedis jedis = null;
        try {
            jedis = jedisPoolUtil.getResource();
            jedis.rpoplpush(key, destination);
        } catch (Exception e) {
            //释放redis对象
        	jedisPoolUtil.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            //返还到连接池
            close(jedis);
        }
    }
    
    /**
     * 获取队列数据
     * @param byte[] key 键名
     * @return
     */
    public List<byte[]> lpopList(byte[] key) {
        List<byte[]> list = null;
        Jedis jedis = null;
        try {
            jedis = jedisPoolUtil.getResource();
            list = jedis.lrange(key, 0, -1);
        } catch (Exception e) {
            //释放redis对象
        	jedisPoolUtil.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            //返还到连接池
            close(jedis);
        }
        return list;
    }
    
    /**
     * 获取队列数据
     * @param byte[] key 键名
     * @return
     */
    public byte[] rpop(byte[] key) {
        byte[] bytes = null;
        Jedis jedis = null;
        try {
            jedis = jedisPoolUtil.getResource();
            bytes = jedis.rpop(key);
        } catch (Exception e) {
            //释放redis对象
        	jedisPoolUtil.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            //返还到连接池
            close(jedis);
        }
        return bytes;
    }
    
    public void hmset(Object key, Map<String, String> hash) {
        Jedis jedis = null;
        try {
            jedis = jedisPoolUtil.getResource();
            jedis.hmset(key.toString(), hash);
        } catch (Exception e) {
            //释放redis对象
        	jedisPoolUtil.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            //返还到连接池
            close(jedis);
        }
    }
    
    public void hmset(Object key, Map<String, String> hash, int time) {
        Jedis jedis = null;
        try {
            jedis = jedisPoolUtil.getResource();
            jedis.hmset(key.toString(), hash);
            jedis.expire(key.toString(), time);
        } catch (Exception e) {
            //释放redis对象
            jedisPoolUtil.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            //返还到连接池
            close(jedis);
        }
    }
 
    public List<String> hmget(Object key, String... fields) {
        List<String> result = null;
        Jedis jedis = null;
        try {
            jedis = jedisPoolUtil.getResource();
            result = jedis.hmget(key.toString(), fields);
        } catch (Exception e) {
            //释放redis对象
            jedisPoolUtil.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            //返还到连接池
            close(jedis);
        }
        return result;
    }
 
    public Set<String> hkeys(String key) {
        Set<String> result = null;
        Jedis jedis = null;
        try {
            jedis = jedisPoolUtil.getResource();
            result = jedis.hkeys(key);
        } catch (Exception e) {
            //释放redis对象
            jedisPoolUtil.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            //返还到连接池
            close(jedis);
        }
        return result;
    }
 
    public List<byte[]> lrange(byte[] key, int from, int to) {
        List<byte[]> result = null;
        Jedis jedis = null;
        try {
            jedis = jedisPoolUtil.getResource();
            result = jedis.lrange(key, from, to);
        } catch (Exception e) {
            //释放redis对象
            jedisPoolUtil.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            //返还到连接池
            close(jedis);
        }
        return result;
    }
 
    public Map<byte[], byte[]> hgetAll(byte[] key) {
        Map<byte[], byte[]> result = null;
        Jedis jedis = null;
        try {
            jedis = jedisPoolUtil.getResource();
            result = jedis.hgetAll(key);
        } catch (Exception e) {
            //释放redis对象
            jedisPoolUtil.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            //返还到连接池
            close(jedis);
        }
        return result;
    }
 
    public void del(byte[] key) {
        Jedis jedis = null;
        try {
            jedis = jedisPoolUtil.getResource();
            jedis.del(key);
        } catch (Exception e) {
            //释放redis对象
            jedisPoolUtil.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            //返还到连接池
            close(jedis);
        }
    }
 
    public long llen(byte[] key) {
        long len = 0;
        Jedis jedis = null;
        try {
            jedis = jedisPoolUtil.getResource();
            jedis.llen(key);
        } catch (Exception e) {
            //释放redis对象
            jedisPoolUtil.returnBrokenResource(jedis);
            e.printStackTrace();
        } finally {
            //返还到连接池
            close(jedis);
        }
        return len;
    }
}
